<?php

class Modules_Pages extends Module {

	public $name = 'pages';
	public $title = "Страницы и структура";

	public static function subMenu() {
		return array(
			array(
				'icon' => '/tpl/admin/images/list.png',
				'url' => '/admin.php?module=pages',
				'title' => 'Список страниц',
			),
			array(
				'icon' => '/tpl/admin/images/add_item.png',
				'url' => '/admin.php?module=pages&action=page_create',
				'title' => 'Добавить страницу',
			),
			array(
				'icon' => '/tpl/admin/images/edit-list.png',
				'url' => '/admin.php?module=pages&action=menu_list',
				'title' => 'Меню сайта',
			),
		);
	}

	public function actions() {
		return array(
			'contextmenu' => "Контекстное меню",
			'mainmenu' => "Главное меню",
		);
	}

	public function mainActions() {
		return array(
			'map' => "Карта сайта",
			'contextmenu' => "Контекстное меню",
		);
	}

	protected function _actionproperties(Blocks  $block) {
		switch ($block->action) {
			case 'contextmenu':
				return $this->contextmenuList($block);
				break;

			case 'mainmenu':
				return $this->mainmenuList($block);
				break;

			default:
				return "Нет";
				break;
		}
	}

	public function adminActionIndex() {
		$this->access("r");

		//$pages = PagesTable::getInstance()->findAll();
		$pages = Doctrine_Query::create()
						->from("Pages p")
						->leftJoin("p.Template")
						->leftJoin("p.MenuItems")
						->execute();
		$this->tpl()->assign('pages', $pages);
		return $this->tpl()->fetch('pages_list.html');
	}

	public function adminActionPage_active() {
		$this->access("p");

		$id = (int) $_REQUEST['id'];
		if (!$id) Request::redirect(404);

		$page = PagesTable::getInstance()->find($id);
		if (!$page) Request::redirect(404);

		$page->active = 1;
		$page->save();

		Request::redirect('?module=pages');
	}

	public function adminActionPage_unactive() {
		$this->access("p");

		$id = (int) $_REQUEST['id'];
		if (!$id) Request::redirect(404);

		$page = PagesTable::getInstance()->find($id);
		if (!$page) Request::redirect(404);

		$page->active = 0;
		$page->save();

		Request::redirect('?module=pages');
	}

	public function adminActionPage_edit() {
		$this->access("c");

		$id = (int) $_REQUEST['id'];
		if (!$id) Request::redirect(404);

		$page = Doctrine_Query::create()
						->from("Pages p")
						->leftJoin("p.Template")
						->leftJoin("p.Blocks b")
						->leftJoin("b.Module")
						->where('p.id = ?', $id)
						->orderBy('b.position')
						->fetchOne();
		if (!$page) Request::redirect(404);

		$fields = array_fill(0, $page->maxField, array());

		foreach ($page->Blocks as $block) {
			$fields[$block->field][] = $block;
		}

		App::registerCoreScript('jquery');
		App::registerCoreScript('colorbox');
		App::registerScript('/inc/Modules/Pages/js/pages_edit.js');
		App::registerCoreStyle('colorbox');

		$this->tpl()->assign(array(
			'page' => $page,
			'tpl_list' => TemplatesTable::getInstance()->findAll(),
			'fields' => $fields,
			'modules_list' => Modules::modulesList(),
		));
		return $this->tpl()->fetch('pages_edit.html');
	}

	public function adminActionPage_create() {
		$this->access("c");

		$page = new Pages();

		App::registerCoreScript('jquery');
		App::registerScript('/inc/Modules/Pages/js/pages_edit.js');

		$this->tpl()->assign(array(
			'page' => $page,
			'tpl_list' => TemplatesTable::getInstance()->findAll(),
		));
		return $this->tpl()->fetch('pages_create.html');
	}

	public function adminActionPage_save() {
		$this->access("c");

		$data = $_REQUEST['page'];
		$data['id'] = (int) $data['id'];

		$page = !empty($data['id']) ? PagesTable::getInstance()->find($data['id']) : new Pages();
		$page->fromArray($data);
		$page->createtime = time();
		$page->link = $page->alias;
		$page->save();
		$this->_checkLinkMenuItem($page);

		 /*if (!$page->save()) {
			App::registerCoreScript('jquery');
			App::registerScript('/inc/Modules/Pages/js/pages_edit.js');

			$this->tpl()->assign(array(
				'errors' => $page->getErrors(),
				'page' => $page,
				'tpl_list' => Templates::model()->findAll(),
			));
			return $this->tpl()->fetch('pages_create.html');
		}*/

		if (empty($data['id']) || isset($_REQUEST['apply'])) {
			Request::redirect("?module=pages&action=page_edit&id={$page->id}");
		} else {
			Request::redirect("?module=pages&action=index");
		}
	}

	public function adminActionPage_home() {
		$this->access("c");

		$id = !empty($_REQUEST['id']) ? $_REQUEST['id'] : 0;
		if (!$id) Request::redirect(404);

		$page = PagesTable::getInstance()->find($id);
		if (!$page) Request::redirect(404);


		$page->is_home = 1;
		$page->save();

		$home_page = Pages::homePage();
		if ($home_page) {
			$home_page->is_home = 0;
			$home_page->save();
		}

		Request::redirect("?module=pages&action=index");
	}

	public function adminActionPage_delete() {
		$this->access("d");

		$id = !empty($_REQUEST['id']) ? $_REQUEST['id'] : 0;
		if (!$id) Request::redirect(404);

		$page = PagesTable::getInstance()->find($id);
		if (!$page) Request::redirect(404);

		$page->delete();
		Request::redirect("?module=pages&action=index");
	}

	public function adminActionActionproperties() {
		$this->access("c");

		$data = $_REQUEST['block'];
		$id = (int) $data['id'];
		$block = $id ? BlocksTable::getInstance()->find($id) : new Blocks();

		$module_id = (int) $data['module_id'];
		$action = $data['action'];
		$page_id = (int) $data['page_id'];
		$field = (int) $data['field'];

		$block->module_id = $module_id;
		$block->action = $action;
		$block->page_id = $page_id;
		$block->field = $field;

		return ModulesTable::getInstance()->find($module_id)->module->actionproperties($block);
	}

	public function adminActionCopy_blocks() {
		$this->access("c");

		$dest_page_id = (int) $_REQUEST['dest_page_id'];
		if (!$dest_page_id) Request::redirect(404);

		$srcPages = Doctrine_Query::create()
						->from("Pages p")
						->leftJoin('p.Blocks')
						->where('p.id != ?', $dest_page_id)
						->execute();

		$this->tpl()->assign(array(
			'dest_page_id' => $dest_page_id,
			'srcPages' => $srcPages,
		));
		return $this->tpl()->fetch($this->getAdminTpl('blocks_copy.html'));
	}

	public function adminActionLoad_src_blocks() {
		$this->access("c");
		
		$src_id = (int) $_REQUEST['src_id'];
		if (!$src_id) Request::redirect(404);

		$srcBlocks = Doctrine_Query::create()
						->from("Blocks b")
						->leftJoin('b.Module m')
						->where('b.page_id = ?', $src_id)
						->andWhere('b.field != 0')
						->orderBy('b.field, b.position')
						->execute();

		$fields = array();
		foreach ($srcBlocks as $sBlock) {
			$fields[$sBlock->field][] = $sBlock;
		}

		$this->tpl()->assign(array(
			"fields" => $fields,
		));
		return $this->tpl()->fetch($this->getAdminTpl('src_blocks.html'));
	}

	public function adminActionSave_copied_blocks() {
		$this->access("c");
		
		$dest_page = isset($_REQUEST['dest_page_id']) ? (int) $_REQUEST['dest_page_id'] : 0;
		$src_page = isset($_REQUEST['src_page']) ? (int) $_REQUEST['src_page'] : 0;
		$blocks = isset($_REQUEST['block']) ? $_REQUEST['block'] : array();
		if (!$dest_page || !$src_page || $src_page == $dest_page || !count($blocks)) Request::redirect(404);

		$src_page = Doctrine_Query::create()
						->from('Pages p')
						->where('p.id = ?', $src_page)
						->fetchOne();

		$dest_page = Doctrine_Query::create()
						->from('Pages p')
						->where('p.id = ?', $dest_page)
						->fetchOne();


		$blocks = array_keys($blocks);
		$blocks = Doctrine_Query::create()
						->from('Blocks b')
						->leftJoin('b.Properties')
						->whereIn('b.id', $blocks)
						//->andWhere('b.page_id = ?', $src_page)
						->execute();

		if (!$src_page || !$dest_page || !count($blocks)) Request::redirect(404);

		$count = 0;
		foreach ($blocks as $k => $block) {
			$maxPos = $this->_maxPos($blocks[$k]->field, $blocks[$k]->page_id) + 1;
			$maxPos = $maxPos ? $maxPos + 1 : 1;
			$blocks[$k]->position = $maxPos;
			$block = $blocks[$k]; //->toArray();

			$_block = $block->copy();
			$_block->page_id = $dest_page;
			$_block->save();

			foreach ($block->Properties as $property) {
				$p = $property->copy();
				$p->block_id = $_block->id;
				$p->save();
			}

			$count++;
		}

		return $count;
	}

	public function adminActionCreateblock() {
		$this->access("c");

		$module_id = (int) $_REQUEST['module_id'];
		$field_id = (int) $_REQUEST['field_id'];
		$page_id = (int) $_REQUEST['page_id'];

		// если главное поле - проверяем количество блоков в нем. Если больше 1 - выводим сообщение об ошибке
		if ($field_id == 0 && count(BlocksTable::getInstance()->findByDql('page_id = ? AND field = ?', array($page_id, $field_id)))) {
			return "В поле №0 может быть только один блок.";
		}

		$block = new Blocks();
		$block->page_id = $page_id;
		$block->field = $field_id;
		$block->module_id = $module_id;

		$this->tpl()->assign(array(
			'block' => $block,
		));
		return $this->tpl()->fetch('block_create.html');
	}

	public function adminActionEditblock() {
		$this->access("c");

		$block = (int) $_REQUEST['id'];
		if (!$block) Request::redirect(404);

		$block = BlocksTable::getInstance()->find($block);
		if (!$block) Request::redirect(404);

		$this->tpl()->assign(array(
			'block' => $block,
		));
		return $this->tpl()->fetch('block_create.html');
	}

	public function adminActionDeleteblock() {
		$this->access("d");

		$id = (int) $_REQUEST['id'];
		if (!$id) Request::redirect(404);
		$block = Doctrine_Query::create()
						->from("Blocks b")
						->leftJoin("b.Properties bp")
						->where("b.id = ?", $id)
						->fetchOne();
		if (!$block) Request::redirect(404);

		$rows = $block->delete();

		return json_encode(array('count' => 1));
	}

	public function adminActionUpblock() {
		$this->access("c");

		$id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
		if (!$id) Request::redirect(404);
		$block = BlocksTable::getInstance()->find($id);
		if (!$block) Request::redirect(404);

		if ($block->position == 1) return 0;

		$q = Doctrine_Query::create()
						->update("Blocks")
						->set("position", "position + 1")
						->where("field = ? AND page_id = ? AND position = ?", array($block->field, $block->page_id, $block->position - 1))
						->limit(1);
		$rows = $q->execute();

		$block->position = $block->position - 1;
		$block->save();

		return $rows;
	}

	public function adminActionDownblock() {
		$this->access("c");

		$id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
		if (!$id) Request::redirect(404);
		$block = BlocksTable::getInstance()->find($id);
		if (!$block) Request::redirect(404);

		$maxPos = $this->_maxPos($block->field, $block->page_id);

		if ($block->position == $maxPos) return 0;

		$q = Doctrine_Query::create()
						->update("Blocks")
						->set("position", "position - 1")
						->where("field = ? AND page_id = ? AND position = ?", array($block->field, $block->page_id, $block->position + 1))
						->limit(1);
		$rows = $q->execute();

		$block->position = $block->position + 1;
		$block->save();


		return $rows;
	}

	public function adminActionSaveblock() {
		$this->access("c");

		$blockData = !isset($_REQUEST['block']) ? array() : $_REQUEST['block'];
		$blockData['id'] = (int) $blockData['id'];

		$block = (!$blockData['id']) ? (new Blocks()) : (BlocksTable::getInstance()->find($blockData['id']));

		$properties = isset($blockData['Properties']) ? $blockData['Properties'] : array();

		$i = 0;
		$blockData['Properties'] = array();
		foreach ($properties as $prop => $value) {
			$blockData['Properties'][$i]['property'] = $prop;
			$blockData['Properties'][$i]['value'] = $value;
			$i++;
		}

		if ($block->id) {
			$q = Doctrine_Query::create()
							->delete("BlocksProperties")
							->where("block_id = ?", $block->id)
							->execute();
		}

		if (!$block->id) {
			$maxPos = $this->_maxPos($blockData['field'], $blockData['page_id']);
			$blockData['position'] = $maxPos ? $maxPos + 1 : 1;

			unset($blockData['id']);
		}


		$block->fromArray($blockData);
		$block->save();

		$this->tpl()->assign(array(
			'block' => $block,
		));
		$r = array(
			'block' => $this->tpl()->fetch('_block.html'),
			'field' => $block->field,
		);

		return json_encode($r);
	}

	public function adminActionMenu_list() {
		$this->access("r");

		$menus = MenusTable::getInstance()->findAll();
		$this->tpl()->assign(array(
			'menus' => $menus,
		));
		return $this->tpl()->fetch('menu_list.html');
	}

	public function adminActionMenu_edit() {
		$this->access("c");

		$id = $_REQUEST['id'];
		if (!$id) Request::redirect(404);
		$menu = MenusTable::getInstance()->find($id);
		if (!$menu) Request::redirect(404);

		return $this->_menu_edit($menu, 'menu_edit.html');
	}

	public function adminActionMenu_create() {
		$this->access("c");

		$menu = new Menus();
		return $this->_menu_edit($menu, 'menu_create.html');
	}

	public function adminActionMenu_save() {
		$this->access("c");

		$id = (int) $_REQUEST['id'];
		$title = $_REQUEST['title'];
		$data = json_decode($_REQUEST['data']);
		$deleteData = json_decode($_REQUEST['deleteData']);

		if ($id) {
			$menu = MenusTable::getInstance()->find($id);
			foreach ($menu->Items as $item) {
				$item->delete();
			}
		} else {
			$menu = new Menus();
		}

		if ($menu->title != $title) {
			$menu->title = $title;
			$menu->save();
		}

		if ($menu->is_map == 1) $this->_unlinkMenuItems($menu->Items);

		foreach ($data as $menuItem) {
			$i = $menuItem->page_id;
			$mI[$i] = new MenuItems();
			$mI[$i]->menu_id = $menu->id;
			$mI[$i]->page_id = $menuItem->page_id;
			$mI[$i]->parent = $menuItem->parent == 0 ? 0 : (isset($mI[$menuItem->parent]) ? $mI[$menuItem->parent]->id : 0);
			$mI[$i]->level = $menuItem->level;
			$mI[$i]->position = $menuItem->position;
			$mI[$i]->save();

			if ($mI[$i]->Page->in_cart == 1) {
				$mI[$i]->Page->in_cart = 0;
				$mI[$i]->Page->save();
			}

			$menuItems[$mI[$i]->id] = $mI[$i];
		}

		if ($menu->is_map == 1) $this->_linkMenuItems($menuItems);

		foreach ($deleteData as $dd) {
			$page = PagesTable::getInstance()->find($dd);
			$page->in_cart = 1;
			$page->save();
		}

		return $menu->id;
	}

	public function adminActionMenu_delete() {
		$this->access("d");

		$id = (int) $_REQUEST['id'];
		if (!$id) Request::redirect(404);
		$menu = MenusTable::getInstance()->find($id);
		if (!$menu) Request::redirect(404);

		$menu->delete();

		Request::redirect('/admin.php?module=pages&action=menu_list');
	}

	public function adminActionMenu_unactive() {
		$this->access("p");

		$id = (int) $_REQUEST['id'];
		if (!$id) Request::redirect(404);
		$menu = MenusTable::getInstance()->find($id);
		if (!$menu) Request::redirect(404);

		$menu->active = 0;
		$menu->save();

		Request::redirect('/admin.php?module=pages&action=menu_list');
	}

	public function adminActionMenu_active() {
		$this->access("p");

		$id = (int) $_REQUEST['id'];
		if (!$id) Request::redirect(404);
		$menu = MenusTable::getInstance()->find($id);
		if (!$menu) Request::redirect(404);

		$menu->active = 1;
		$menu->save();

		Request::redirect('/admin.php?module=pages&action=menu_list');
	}

	public function adminActionMenu_map() {
		$this->access("c");

		$id = (int) $_REQUEST['id'];
		if (!$id) Request::redirect(404);

		$menu = MenusTable::getInstance()->find($id);
		if (!$menu) Request::redirect(404);

		$map = Menus::mainMenu();
		if ($map) {
			$map->is_map = 0;
			$map->save();
			$this->_unlinkMenuItems($map->Items);
		}

		$menu->is_map = 1;
		$menu->save();
		$this->_linkMenuItems($menu->Items);

		Request::redirect('/admin.php?module=pages&action=menu_list');
	}

	private function _checkLinkMenuItem(Pages $page) {
		$menu = Menus::mainMenu();
		$menuItems = Doctrine_Query::create()
						->from("MenuItems mi")
						->where('mi.page_id = ?', $page->id)
						->andWhere('mi.menu_id = ?', $menu->id)
						->execute();

		if (count($menuItems) > 0) {
			$this->_linkMenuItems($menuItems);
		}
	}

	private function _buildChain($item, $items) {
		$chain[] = $item->Parent->Page;
		if ($item->Parent->parent != 0) {
			$chain = array_merge($chain, $this->_buildChain($item->Parent, $items));
		}

		return $chain;
	}

	private function _linkMenuItems($menuItems) {
		foreach ($menuItems as $item) {
			$chain = array();
			if ($item->parent != 0) {
				$chain = $this->_buildChain($item, $menuItems);
			}

			$chain = array_reverse($chain);
			$str = array();
			foreach ($chain as $p) {
				$str[] = $p->alias;
			}
			$str[] = $item->Page->alias;

			$str = join('/', $str);

			$item->Page->link = $str;
			$item->Page->save();
		}
	}

	private function _unlinkMenuItems($menuItems) {
		foreach ($menuItems as $item) {
			$item->Page->link = $item->Page->alias;
			$item->Page->save();
		}
	}

	private function _menu_edit(Menus $menu, $tpl) {
		App::registerCoreScript('jquery');
		App::registerCoreScript('jstree');
		App::registerScript('/inc/Modules/Pages/js/menu_edit.js');
		App::registerScript('/js/jquery.json-2.2.js');

		$this->tpl()->assign(array(
			'menu' => $menu,
			'in_cart' => PagesTable::getInstance()->findByIn_cart(1),
		));

		return $this->tpl()->fetch($tpl);
	}

	public function actionContextmenu() {
		$menu = (int) $this->block->property('menu')->value;
		if (!$menu) return "";

		$menu = MenusTable::getInstance()->find($menu);
		if (!$menu) return "";

		$tpl = $this->getTpl('mainmenu.html');

		$this->tpl()->assign(array(
			"menu" => $menu
		));
		return $this->tpl()->fetch($tpl);
	}

	public function actionMainmenu() {
		$menu = Menus::mainMenu();
		if (!$menu) return "";

		$this->tpl()->assign(array(
			"menu" => $menu
		));
		return $this->tpl()->fetch($this->getTpl('mainmenu.html'));
	}

	public function contextmenuList($block) {
		$menus = MenusTable::getInstance()->findByDql('is_map = ?', array(0));
		$this->tpl()->assign(array(
			"menus" => $menus,
			"block" => $block,
			"tpls" => $this->avaliableTemplatesList('contextmenu', $block),
		));

		return $this->tpl()->fetch('actionproperties.html');
	}

	public function mainmenuList($block) {
		$this->tpl()->assign(array(
			"block" => $block,
			"tpls" => $this->avaliableTemplatesList('mainmenu', $block),
		));

		return $this->tpl()->fetch('actionproperties.html');
	}

	private function _maxPos($field, $page_id) {
		$maxPos = Doctrine_Query::create()
						->select('MAX(position) AS maxPos')
						->from('Blocks')
						->where('field = ? AND page_id = ?', array($field, $page_id))
						->fetchOne()
						->toArray();

		return $maxPos['maxPos'];
	}

}